# coding= utf-8

import requests
import json
import sys
import codecs
import warnings
import pymongo
import time
from datetime import datetime

sys.stdout = codecs.getwriter('utf-8')(sys.stdout.detach())
warnings.filterwarnings("ignore")


class Keepa:
    def __init__(self):
        self.lr = {}
        self.api_prefix = 'https://api.keepa.com/product'
        self.api_current = ''
        # self.api_key1 = '2dk1l3e09o7hvjhcqg67lnrspsmmp3at0jikcsu9e8f257kstasjvev8thh0g1uv'
        # self.new_token = '6nokjd8r4ev0aq7ic6sktl1a1nc2a7l3eqr6k91l85qhtdkm1g9fvhmrbq8uapki'  # 新账户token
        self.api_key = 'r4mmbkscb3hgclav1f45dpg61tf0gga07eb91kbfqf253dl99d5jdvfkil1scvec'  # 付费token
        self.asset_url = 'https://m.media-amazon.com/images/I/'
        self.token_url = 'https://api.keepa.com/token'
        self.asin_list = []
        self.domain = ''
        self.locale = ''
        self.month = sys.argv[1]
        # self.month = '2024-02'
        self.asin_num = {}
        self.asin_counts = {}
        self.sku_count = {}
        self.group_name = {}

        # 连接MongoDB
        # current_datetime = datetime.datetime.now()
        # current_year = current_datetime.year
        self.myclient = pymongo.MongoClient("mongodb://localhost:27017/")
        mydb = self.myclient["xp_analyse"]
        self.my_asin = mydb["wt_order_asin"]
        self.my_product = mydb["wt_order_product"]
        self.my_task = mydb["wt_task"]

    def get_asin(self, domain, asin):
        # print(self.asin_num)
        url = self.api_prefix
        params = {
            'key': self.api_current,
            'domain': int(domain),
            'asin': asin,
            'rating': 1,
            'stats': 180,
            'update': 6,
            'history': 0
        }
        response = requests.get(url=url, params=params)

        # 判断状态码
        status_code = response.status_code
        if not int(status_code) == 200:
            print('状态码：' + str(status_code) + '请求失败，等待下次重试！')
            # self.myclient.close()
            # exit()
        else:
            res = json.loads(response.text)

            # 请求成功添加至数据库
            my_list = []

            # 判断请求是否成功
            if "error" in res:
                print(res['error']['message'])

            if "products" in res:
                for i in res['products']:
                    # 判断没有分类树，略过
                    if 'categories' not in i or i['categories'] == None or len(i['categories']) == 0:
                        continue

                    sales_rank_current = int(i['stats']['current'][3])
                    reviews_review_count = int(i['stats']['current'][17])
                    category = {}
                    category_list = []

                    if 'imagesCSV' in i and not i['imagesCSV'] == None:
                        image = i['imagesCSV'].split(',')[0]
                    else:
                        image = ''
                    if 'categoryTree' in i:
                        category_tree = i['categoryTree']
                    else:
                        category_tree = ''
                    if category_tree:
                        for tree in category_tree:
                            category[int(tree['catId'])] = tree['name']
                            category_list.append(tree['name'])
                        if i.get('salesRankReference', '') in category:
                            salesRankReference = category[int(i.get('salesRankReference', ''))]
                        else:
                            salesRankReference = int(i.get('salesRankReference', ''))
                    else:
                        salesRankReference = ''

                    # 获取父级分类ID和name
                    if not category_tree == None:
                        parent_cate = category_tree[(len(category_tree) - 1)]
                        root_cate = category_tree[0]
                    else:
                        parent_cate = {
                            'catId': i['categories'][0],
                            'name': ''
                        }
                        root_cate = {
                            'catId': i['rootCategory'],
                            'name': ''
                        }
                    order_num = self.asin_num[i['asin']]
                    order_counts = self.asin_counts[i['asin']]
                    sku_count = self.sku_count[i['asin']]
                    group_name = self.group_name[i['asin']]
                    value = dict([
                        ['locale', translate_domain(int(self.domain))],
                        ['month', self.month],
                        ['domain_id', int(domain)],
                        ['category_id', parent_cate['catId']],
                        ['category_name', parent_cate['name']],
                        ['root_category', root_cate['name']],
                        ['asin', i.get('asin', '')],
                        ['order_num', order_num],
                        ['order_counts', order_counts],
                        ['sku_count', sku_count],
                        ['group_name', group_name],
                        ['image', self.asset_url + image],
                        ['title', i.get('title', '')],
                        ['sales_rank_current', sales_rank_current],
                        ['sales_rank_reference', salesRankReference],
                        ['bought_in_past_month', i.get('monthlySold', '')],
                        ['reviews_rating', float(i['stats']['current'][16] / 10)],
                        ['reviews_review_count', reviews_review_count],
                        ['buy_box_current', float(i['stats']['current'][1] / 100)],
                        ['tracking_since', translate_time(int(i.get('trackingSince', '')))],
                        ['categories_tree', ' > '.join(category_list)],
                        ['create_time', int(time.time())],
                        ['update_time',  int(time.time())],
                    ])
                    my_list.append(value)

                # print(my_list)
                # exit()
                if len(my_list) > 0:
                    result = self.my_product.insert_many(my_list)
                    # 检查插入操作是否成功
                    if result.acknowledged:
                        print('获取产品成功，共计' + str(len(my_list)) + '条！')
                    else:
                        print('插入失败，等待下次重新获取！')
                else:
                    print('本次请求无给定asin列表数据！')

                # 标记已获取产品信息的asin
                if self.my_asin.update_many({'month': self.month, 'asin': {'$in': self.asin_list}, "country": self.locale}, {'$set': {'keepaed': True}}):
                    print('标记已获取信息asin，共计' + str(len(self.asin_list)) + '条！')
                else:
                    print('标记失败，等待下次标记！')
            else:
                print('返回结果无产品！')
            # self.myclient.close()
            # exit()

    def pre_asin(self):
        # 判断令牌剩余数量
        params = {
            'key': self.api_key
        }
        response = requests.get(url=self.token_url, params=params)
        res = json.loads(response.text)
        token_left = int(res['tokensLeft'])

        # 令牌不足退出
        if token_left < 300:
            print('Token不足， 剩余 ' + str(token_left))
            # self.myclient.close()
            # exit()
        else:
            print('Token剩余 ' + str(token_left))
            self.api_current = self.api_key
            asins = self.my_asin.find({'keepaed': {'$exists': False}, 'month': self.month, 'country': {"$in": ['it', 'de', 'us', 'uk', 'fr', 'jp', 'ca', 'es']}, 'asin': {"$ne": None, '$exists': True}}).sort('country', 1).limit(100)
            asins_list = list(asins)
            asin_num = len(asins_list)

            if asin_num <= 0:
                print('Asin Is Complete!')
                self.my_task.update_one({"month": self.month}, {"$set": {"order_product_completed": 'completed'}})
                self.myclient.close()
                exit()
            else:
                self.locale = asins_list[0]['country']
                self.domain = translate_locale(self.locale)
                for i in asins_list:
                    self.asin_num[i['asin']] = i['order_num']
                    self.asin_counts[i['asin']] = i['order_counts']
                    self.sku_count[i['asin']] = i['sku_count']
                    self.group_name[i['asin']] = i['group_name']
                    if i['country'] == self.locale:
                        self.asin_list.append(i['asin'])
                print('asin列表获取成功，国家为'+str(self.locale) + '， 共计:' + str(len(self.asin_list)))

                # 获取keepa产品信息
                if len(self.asin_list) > 0:
                    asin = ','.join(self.asin_list)
                    self.get_asin(self.domain, asin)

    def run_all_asin(self):
        total_num = self.my_asin.find({'keepaed': {'$exists': False}, 'month': self.month, 'country': {"$in": ['it', 'de', 'us', 'uk', 'fr', 'jp', 'ca', 'es']}}).count()
        if total_num > 0:
            while True:
                time.sleep(20)
                self.asin_list = []
                self.pre_asin()
        else:
            print('该月份数据已生成！')
            # 更新状态为已完成
            self.my_task.update_one({"month": self.month}, {"$set": {"order_product_completed": 'completed'}})
        self.myclient.close()
        exit()

    def run_test(self):
        # 更新状态为处理中
        self.my_task.update_one({"month": self.month}, {"$set": {"order_product_completed": 'pending'}})

        date_04 = datetime.strptime("2024-04", '%Y-%m')
        date_sys = datetime.strptime(self.month, '%Y-%m')
        if date_sys < date_04:
            total = self.my_asin.find({'keepaed': {'$exists': False}, 'month': self.month})
            sames = []
            keepaed = []
            for i in total:
                same_item = self.my_product.find_one({"locale": i['country'], 'asin': i['asin']})
                if same_item:
                    same_item['month'] = self.month
                    del same_item['_id']
                    same_item['order_num'] = i['order_num']
                    same_item['order_counts'] = i['order_counts']
                    same_item['sku_count'] = i['sku_count']
                    same_item['group_name'] = i['group_name']
                    sames.append(same_item)
                    keepaed.append(i['asin'])
            if len(sames):
                re = self.my_product.insert_many(sames)
                act = self.my_asin.update_many({'month': self.month, 'asin': {"$in": keepaed}}, {"$set": {"keepaed": True}})
                print(re.acknowledged)
                print(act.modified_count)
                print('根据历史记录获取产品成功')
            else:
                print('等待keepa获取')
        self.run_all_asin()


def translate_domain(domain):
    dis = {1: 'us', 2: 'uk', 3: 'de', 4: 'fr', 5: 'jp', 6: 'ca', 8: 'it', 9: 'es', 10: 'in', 11: 'mx'}
    return dis.get(domain)


def translate_locale(domain):
    dis = {'us': 1, 'uk': 2, 'de': 3, 'fr': 4, 'jp': 5, 'ca': 6, 'it': 8, 'es': 9, 'in': 10, 'mx': 11}
    return dis.get(domain)


def translate_time(keepa_time):
    return (keepa_time + 21564000) * 60


keepa = Keepa()
keepa.run_test()


